#
# Copyright 2008 Charles Connell <charles@connells.org>
#
# This file is part of Tuxedo.
#
# Tuxedo is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# Tuxedo is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with Tuxedo; if not, see <http://gnu.org/licenses/.>
#

import os
import sys
import gtk
import gtk.gdk
import task
from task import Task
import pango
from config import Config
import statusconfig
from statusconfig import StatusConfig

class ConfigDialog:
    """Creates the dialog box for configuring Tuxedo."""
    def onApply(self, data):
        """Transfers information to configuration backend."""
        config = Config()
        config.setPriorityColors(self.prioritycolors)
        config.setTextColors(self.textcolors)
        config.setPriorityNames(self.prioritynames)
        config.setStatusNames(self.statusnames)
        config.setStatusOptions(self.statusoptions)
        config.save()

    def onOK(self, data):
        """Save config and close dialog."""
        self.onApply(data)

        # Close the dialog
        self.dialog.destroy()

    def onCancel(self, data):
        """Closes the dialog."""
        self.dialog.destroy()

    def onDefaults(self, data):
        """Set settings to some nice values."""
        self.prioritycolors[task.TASK_PRIORITY_LOWEST] = '#9999FF'
        self.prioritycolors[task.TASK_PRIORITY_LOW] = '#CCCCFF'
        self.prioritycolors[task.TASK_PRIORITY_NORMAL] = '#FFFFFF'
        self.prioritycolors[task.TASK_PRIORITY_HIGH] = '#FFAAAA'
        self.prioritycolors[task.TASK_PRIORITY_HIGHEST] = '#FF4444'

        self.textcolors[task.TASK_PRIORITY_LOWEST] = '#000000'
        self.textcolors[task.TASK_PRIORITY_LOW] = '#000000'
        self.textcolors[task.TASK_PRIORITY_NORMAL] = '#000000'
        self.textcolors[task.TASK_PRIORITY_HIGH] = '#000000'
        self.textcolors[task.TASK_PRIORITY_HIGHEST] = '#000000'

        self.prioritynames[task.TASK_PRIORITY_LOWEST] = 'Lowest'
        self.prioritynames[task.TASK_PRIORITY_LOW] = 'Low'
        self.prioritynames[task.TASK_PRIORITY_NORMAL] = 'Normal'
        self.prioritynames[task.TASK_PRIORITY_HIGH] = 'High'
        self.prioritynames[task.TASK_PRIORITY_HIGHEST] = 'Highest'

        self.statusnames[task.TASK_NOTSTARTED] = 'Not Started'
        self.statusnames[task.TASK_INPROGRESS] = 'In Progress'
        self.statusnames[task.TASK_COMPLETED] = 'Completed'

        self.statusoptions[task.TASK_NOTSTARTED] = [False, False, False, False] # Normal
        self.statusoptions[task.TASK_INPROGRESS] = [False, True, False, False] # Italized
        self.statusoptions[task.TASK_COMPLETED] = [False, False, False, True] # Strikethrough

        self.refreshList()

    def refreshList(self):
        """Refreshes the list of tasks"""
        # Clear the current list of tasks
        self.tasklist.clear()

        # One task for each priority, named after the priority itself
        tasks = []
        for i in range(0,5):
            tasks.append(Task(name=self.prioritynames[i] + ' Priority', priority=i, status=task.TASK_NOTSTARTED))

        # One task for each status, appropriately named
        for i in range(0,3):
            tasks.append(Task(name=self.statusnames[i] + ' Status', priority=task.TASK_PRIORITY_NORMAL, status=i))

        # Append tasks to the ListStore
        for t in tasks:
            self.tasklist.append([t.name, t.priority, t.status])

    def onRowClick(self, treeview, path, column):
        """Opens the edit dialog when a task is double clicked"""
        model, iter = self.taskview.get_selection().get_selected()

        # Read the task information from the TreeView
        t = Task()
        t.name = model.get_value(iter, 0)
        t.priority = model.get_value(iter, 1)
        t.status = model.get_value(iter, 2)

        # The first five are used for priority config, so open that dialog
        if not path[0] >= 5:
            self.priorityConfig(t)
        # The rest are used for status config
        else:
            self.statusConfig(t)

        # Once settings have been changed, redo the list with the new names. New effects will be drawn automatically
        self.refreshList()

    def priorityConfig(self, t):
        """Show dialog allowing user to configure preferences for a specific priority."""
        # Set the path to the glade file to be the path to PriorityConfig.glade
        gladefile = os.path.join(os.path.dirname(sys.argv[0]), 'PriorityConfig.glade')

        # Read the widgets from the glade file
        widgets = gtk.glade.XML(gladefile)
        dialog = widgets.get_widget('PriorityConfig')
        backgroundcolorsel = widgets.get_widget('backgroundcolorsel')
        textcolorsel = widgets.get_widget('textcolorsel')
        nameentry = widgets.get_widget('nameentry')

        # Set initial settings in dialog to current settings
        backgroundcolorsel.set_current_color(gtk.gdk.color_parse(self.prioritycolors[t.priority]))
        textcolorsel.set_current_color(gtk.gdk.color_parse(self.textcolors[t.priority]))
        nameentry.set_text(self.prioritynames[t.priority])

        # Include name of priority in dialog title
        dialog.set_title('Configure ' + self.prioritynames[t.priority] + ' Priority - Tuxedo')

        # If user has clicked "OK", remember user's choices
        if dialog.run() == gtk.RESPONSE_OK:
            # Turn RGB int values into strings
            newbackgroundcolor = backgroundcolorsel.get_current_color()
            newbackgroundcolor_str = '#%04X%04X%04X' % (newbackgroundcolor.red, newbackgroundcolor.green, newbackgroundcolor.blue)
            newtextcolor = textcolorsel.get_current_color()
            newtextcolor_str = '#%04X%04X%04X' % (newtextcolor.red, newtextcolor.green, newtextcolor.blue)

            # Remember user's choices
            self.prioritycolors[t.priority] = newbackgroundcolor_str
            self.textcolors[t.priority] = newtextcolor_str
            self.prioritynames[t.priority] = nameentry.get_text()

        dialog.destroy()

    def statusConfig(self, t):
        """Show dialog allowing user to configure preferences for a specific status."""
        dialog = StatusConfig(self.statusoptions[t.status], self.statusnames[t.status])

        # Include name of status in dialog title
        dialog.dialog.set_title('Configure ' + self.statusnames[t.status] + ' Status - Tuxedo')

        # If user has clicked "OK", remember user's choices
        if dialog.dialog.run() == gtk.RESPONSE_OK:
            self.statusoptions[t.status] = dialog.get_options()
            self.statusnames[t.status] = dialog.get_name()

        dialog.dialog.destroy()


    def taskViewProperties(self, column, cell, model, iter, user_data):
        """Set display effects depending on task properties"""

        # Set the background color and foreground color depending on the task priority
        priority = model.get_value(iter, 1)
        cell.set_property('background', self.prioritycolors[priority])
        cell.set_property('foreground', self.textcolors[priority])

        # Set the text style options depending on the task status
        status = model.get_value(iter, 2)
        # Bold weight or normal weight
        if self.statusoptions[status][statusconfig.STATUS_BOLD] is True:
            cell.set_property('weight', 700)
        else:
            cell.set_property('weight', 400)
        # Italic or normal
        if self.statusoptions[status][statusconfig.STATUS_ITALIC] is True:
            cell.set_property('style', pango.STYLE_ITALIC)
        else:
            cell.set_property('style', pango.STYLE_NORMAL)
        # Maybe underlined and maybe strikethrough
        cell.set_property('underline', self.statusoptions[status][statusconfig.STATUS_UNDERLINE])
        cell.set_property('strikethrough', self.statusoptions[status][statusconfig.STATUS_STRIKETHROUGH])

    def __init__(self):
        """Reads the glade file and creates the dialog."""
        # Set the path to the glade file to be the path to ConfigDialog.glade
        gladefile = os.path.join(os.path.dirname(sys.argv[0]), 'ConfigDialog.glade')

        # Read the widgets from the glade file and connect the signals
        self.widgets = gtk.glade.XML(gladefile)
        self.dialog = self.widgets.get_widget('ConfigDialog')
        signals = {"on_OK" : self.onOK,
                   "on_Apply" : self.onApply,
                   "on_Defaults" : self.onDefaults,
                   "on_Cancel" : self.onCancel,
                   "on_RowActivated" : self.onRowClick,
                   }
        self.widgets.signal_autoconnect(signals)

        # Create a text renderer
        self.cell = gtk.CellRendererText()

        # Create a ListStore to store the tasks in
        self.tasklist = gtk.ListStore(str, int, int)

        # Get the TreeView from the glade file and set it to use the ListStore
        self.taskview = self.widgets.get_widget('treeview')
        self.taskview.set_model(self.tasklist)

        # Add columns to the TreeView
        self.taskcolumn = gtk.TreeViewColumn('Task', self.cell, text=0)
        self.taskview.append_column(self.taskcolumn)

        # Call taskViewProperties to set up the different styles for different priorities
        self.taskcolumn.set_cell_data_func (self.cell, self.taskViewProperties, None)

        # Get own copies of config data
        config = Config()
        self.prioritycolors = config.priorityColors()
        self.textcolors = config.textColors()
        self.prioritynames = config.priorityNames()
        self.statusnames = config.statusNames()
        self.statusoptions = config.statusOptions()

        # Fill treeview with example tasks
        self.refreshList()



